﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MineDiscover.Interfaces;
using MineDiscover.Utils;

namespace MineDiscover
{
    public class MapMine
    {
        public Tile[,] Tiles { get; set; }
        private int columns;
        private int rows;

        // Beginner
        public MapMine() : this(RuleManager.GetDifficultDefault(DifficultType.Beginner)) {  }
        
        public MapMine(Difficulty difficulty)
        {
            this.columns = difficulty.Columns;
            this.rows = difficulty.Rows;

            Tiles = new Tile[columns, rows];

            for (int i = 0; i < columns; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    Tiles[i, j] = new Tile(TileState.Close);
                    Tiles[i, j].positionInMap = new Position(i, j);
                }
            }
        }

        public void TileRightClick(Tile tile)
        {
            if (tile.TileState != TileState.Open)
            {
                switch (tile.TileState)
                {
                    case TileState.Close:
                        tile.TileState = TileState.Flag;
                        break;
                    case TileState.Flag:
                        tile.TileState = TileState.Suspect;
                        break;
                    case TileState.Suspect:
                        tile.TileState = TileState.Close;
                        break;
                }
            }
        }

        public void TileLeftClick(Tile tile)
        {
            Open(tile);
        }

        public bool IsMine(int x, int y)
        {
            if (Helper.ValidateOverBoundary(x, y, rows, columns))
            {
                return Tiles[x, y].IsMine;
            }
            return false;
        }

        private void Open(Tile tile)
        {
            if (tile.TileState != TileState.Open && tile.TileState != TileState.Flag)
            {
                tile.TileState = TileState.Open;

                int countMineArround = CountAroundMines(tile);

                if (countMineArround > 0)
                {
                    tile.MinesArround = countMineArround;
                }
                else
                {
                    for (int i = 0; i < Helper.ArrayIndexArround.Length; i += 2)
                    {
                        OpenResusion(tile.positionInMap.X + Helper.ArrayIndexArround[i], tile.positionInMap.Y + Helper.ArrayIndexArround[i + 1]);
                    }
                }
            }
        }

        private int CountAroundMines(Tile tile)
        {
            int count = 0;
            for (int i = 0; i < Helper.ArrayIndexArround.Length; i += 2)
            {
                if (IsMine(tile.positionInMap.X + Helper.ArrayIndexArround[i], tile.positionInMap.Y + Helper.ArrayIndexArround[i + 1]))
                {
                    count++;
                }
            }
            return count;
        }

        private void OpenResusion(int x, int y)
        {
            if (Helper.ValidateOverBoundary(x, y, rows, columns))
            {
                Open(Tiles[x, y]);
            }
        }
    }
}
